#ifndef VL_ARRAY_PROP__H_
#define VL_ARRAY_PROP__H_

#include <vector>
#include <functional>
#include <set>
#include "vl_prop.h"

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 14:37:56
 * 
 * 数组属性
 */
class ArrayProp: public VLProp {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-04 18:11:54
	 * 
	 * ForEach 函数定义
	 * @param value 数组项值
	 * @return 如果需要中断遍历返回 false
	 */
	using ForEach = std::function<bool(const std::string& value)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:38:14
	 * 
	 * 构造方法
	 */
	explicit ArrayProp();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:38:14
	 * 
	 * 构造方法
	 * @param name 指定数组名
	 */
	explicit ArrayProp(std::string name);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:39:48
	 * 
	 * 方法重载, 根据标从数组中获取属性
	 * @param index 数组下标
	 * @return 属性指针
	 */
	std::shared_ptr<VLProp> operator [](unsigned int index);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:45:06
	 * 
	 * 数组中添加属性
	 * @param prop 属性指针
	 */
	void operator ()(VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:45:06
	 * 
	 * 数组中添加属性
	 * @param prop 属性指针
	 */
	void operator ()(std::shared_ptr<VLProp> prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:46:35
	 * 
	 * 数组中直接添加属性值
	 * 
	 * @param propValue 属性值
	 */
	void operator ()(std::string propValue);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:25:58
	 * 
	 * 删除指定下标元素
	 * 
	 * @param index 下标
	 */
	ArrayProp& operator -(unsigned int index);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:27:00
	 * 
	 * 数组中添加属性
	 * 
	 * @param prop 属性指针
	 */
	ArrayProp& operator +(VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:27:00
	 * 
	 * 数组中添加属性
	 * 
	 * @param prop 属性指针
	 */
	ArrayProp& operator +(std::shared_ptr<VLProp> prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:27:00
	 * 
	 * 数组中直接添加属性值
	 * 
	 * @param propValue 属性值
	 */
	ArrayProp& operator +(const std::string& prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:27:00
	 * 
	 * 数组中直接添加属性值
	 * 
	 * @param propValue 属性值
	 */
	void add(const std::string& propValue);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-04 18:13:42
	 * 
	 * 遍历数组属性
	 * @param forEachFunc 属性函数
	 */
	void foreach(ForEach forEachFunc);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-25 20:08:16
	 * 
	 * 克隆当前属性
	 * 
	 * @return 属性指针
	 */
	virtual VLProp* clone();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-30 18:22:06
	 * 
	 * 比较两个 Array 之间的区别
	 * @param prop 属性指针
	 * @return 如果相同返回 true
	 */
	virtual bool diff(VLProp* prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-30 19:14:40
	 * 
	 * 组合属性
	 * @param prop 属性指针
	 * 
	 * @return 组合成功返回 false
	 */
	virtual bool combine(std::shared_ptr<VLProp>& prop);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-11-07 18:00:52
	 * 
	 * 判断数组中是否包含某值
	 * 
	 * @param value 值字符串
	 * 
	 * @return 如果包含返回 true
	 */
	bool contain(const std::string& value);
	
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:58:30
	 * 
	 * 删除指定下标元素
	 * @param index 下标
	 */
	void remove(unsigned int index);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:58:30
	 * 
	 * 清空全部元素
	 */
	void clear();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:47:54
	 * 
	 * 获取数组长度
 	 * @return 数组长度
	 */
	unsigned int size();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 11:04:46
	 * 
	 * 构建属性打印信息
	 */
	virtual std::string buildPropPrintInfo();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 15:16:41
	 * 
	 * 打印属性节点信息, 设置前缀
	 * @param prefix 前缀
	 */
	virtual void printWithPrefix(std::string prefix);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 18:51:05
	 * 
	 * 获取 Array 的起始迭代器
	 * 
	 * @return Array 的起始迭代器
	 */
	std::vector<std::shared_ptr<VLProp>>::iterator begin();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-19 18:51:05
	 * 
	 * 获取 Array 的终止迭代器
	 * 
	 * @return Array 的终止迭代器
	 */
	std::vector<std::shared_ptr<VLProp>>::iterator end();

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 17:51:55
	 * 
	 * 友元类
	 */
	friend class RootProp;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-06-21 14:47:30
	 * 
	 * 数组 vector
	 */
	std::vector<std::shared_ptr<VLProp>> array;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-24 18:46:54
	 * 
	 * 去重 Set
	 */
	std::set<std::string> conflictSet;
};

}

#endif // VL_ARRAY_PROP__H_
